import Taro from "@tarojs/taro";
import { AES, enc, mode, pad, MD5 } from "crypto-js";
import { userInfoStore } from "@/stores/userInfoStore";
import { getDictDataTypeList } from "@/api/index";

/**
 * 加载UI中的图片地址，实现预加载
 * @param ui  UI数据，对象模式
 * @param key 需要加载的key值
 */
export const preloadImg = (ui: Record<string, any>, keys: string[] | string) => {
  const determineKey = (key: string, keys: string[] | string) => {
    if (typeof keys === "string") {
      if (keys === key) {
        return true;
      }
    }
    if (Array.isArray(keys)) {
      if (keys.includes(key)) {
        return true;
      }
    }
    return false;
  };
  for (const key in ui) {
    if (Object.hasOwnProperty.call(ui, key)) {
      const item = ui[key];
      if (determineKey(key, keys)) {
        Taro.getImageInfo({
          src: item,
        });
      } else if (typeof item === "object" && item !== null && item.constructor === Object) {
        preloadImg(item, keys);
      }
    }
  }
};

/**
 * 加载UI中的图片地址，实现预加载(批量|去重)
 *
 * new loadImage(nestedObj).start(getImage, 10, (a, b) => {console.log(a + 1, b);})
 * function getImage(url) {
    return new Promise((resolve, reject) => {
      tt.getImageInfo({
        src: url,
        success: (res) => {
          resolve(res)
        },
        fail: (res) => {
          reject(res)
        },
      });
    })

  }
 */
export class loadImage {
  loadUI: any = null;

  constructor(loadUI: any) {
    this.loadUI = loadUI;
  }

  /**
   * 加载图片
   * @param {*} concurrent
   */
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  async start(loadFunction: () => any, concurrent: any = 3, progressCallBack: () => void = () => {}) {
    const imageList = Array.from(this.traverseObject(this.loadUI)) as string[];
    await this.preloadImages(imageList, loadFunction, concurrent, progressCallBack);
  }

  /**
   * 判断是否是有效的URL
   * @param {*} str
   * @returns
   */
  isValidURL(str: string) {
    try {
      new URL(str);
      return true;
    } catch {
      return false;
    }
  }

  /**
   * 判断是否是图片链接
   * @param {*} url
   * @returns
   */
  isImageURL(url: string) {
    const regex = /\.(jpg|jpeg|png|gif|bmp|svg|tiff|webp)$/i;
    return regex.test(url);
  }

  traverseObject(obj: any, prefix = "", imageURLs = new Set()) {
    if (Array.isArray(obj)) {
      // 处理数组
      obj.forEach((value, index) => {
        const newPrefix = `${prefix}[${index}]`;
        if (typeof value === "object" && value !== null) {
          // 如果数组项是对象，则递归调用
          this.traverseObject(value, newPrefix, imageURLs);
        } else if (typeof value === "string" && this.isImageURL(value) && this.isValidURL(value)) {
          // 如果数组项是图片链接，则添加到图片链接集合中
          imageURLs.add(value);
        } else {
          // console.log(`${newPrefix}: ${value}`);
        }
      });
    } else if (typeof obj === "object" && obj !== null) {
      // 处理对象
      for (const key in obj) {
        const newPrefix = `${prefix}.${key}`;
        if (typeof obj[key] === "object" && obj[key] !== null) {
          // 如果对象的属性是对象，则递归调用
          this.traverseObject(obj[key], newPrefix, imageURLs);
        } else if (typeof obj[key] === "string" && this.isImageURL(obj[key]) && this.isValidURL(obj[key])) {
          // 如果对象的属性是图片链接，则添加到图片链接集合中
          imageURLs.add(obj[key]);
        } else {
          // console.log(`${newPrefix}: ${obj[key]}`);
        }
      }
    } else {
      if (obj === "string" && this.isImageURL(obj) && this.isValidURL(obj)) {
        imageURLs.add(obj);
      }
    }
    return imageURLs; // 返回图片链接集合
  }

  async preloadImages(
    imageURLs: string[],
    loadFunction: () => void,
    concurrent = 3,
    // eslint-disable-next-line @typescript-eslint/no-empty-function
    progressCallBack: () => void = () => {},
  ) {
    if (typeof loadFunction !== "function") {
      // eslint-disable-next-line @typescript-eslint/no-empty-function
      loadFunction = () => {};
    }
    if (!Array.isArray(imageURLs)) {
      throw new Error("imageURLs is not an array");
    }
    if (imageURLs.length === 0) {
      throw new Error("imageURLs is empty");
    }
    if (concurrent < 1) {
      throw new Error("concurrent is less than 1");
    }

    const results: PromiseSettledResult<() => void>[] = [];
    let index = 0;

    // Helper function to load images in batches
    async function loadBatch() {
      if (index >= imageURLs.length) return; // Exit if all images are processed
      const batch: Array<() => void> = [];
      for (let i = 0; i < concurrent && index < imageURLs.length; i++, index++) {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        typeof progressCallBack === "function" && progressCallBack(index, imageURLs.length);
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore
        batch.push(loadFunction(imageURLs[index]));
      }

      const batchResults = await Promise.allSettled(batch);
      results.push(...batchResults);
      await loadBatch();
    }

    await loadBatch();
    return results;
  }
}

/**验证手机号
 * @param text 手机号字符串
 */
export const verifyPhone = (text: string) => /^1[3-9]\d{9}$/.test(text);

/**
 * 数字补零
 * @param number 需要补零的数字
 * @param width 补零的长度,默认为2
 * @returns 补零后的结果 例如 传入7,得到07
 */
export const zeroPad = (number: number, width = 2) => {
  // 将数字转换为字符串
  const numStr = number.toString();

  // 计算需要补零的位数
  const padding = width - numStr.length;

  // 如果需要补零，则在数字前面添加零
  if (padding > 0) {
    return "0".repeat(padding) + numStr;
  } else {
    return numStr;
  }
};

/**
 * 对象转链接参数 {a:1,b:2} 转成 a=1&b=2
 * ps:新浏览器使用URLSearchParams这个也可以哦
 * @param obj 对象
 * @returns 字符串
 */
export const objectToQueryString = (obj: { [key: string]: any }) => {
  const queryParams: string[] = [];
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      queryParams.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]));
    }
  }
  return queryParams.join("&");
};

/**
 * 链接参数转对象 a=1&b=2 转成 {a:1,b:2}
 * ps:新浏览器使用URLSearchParams这个也可以哦
 * @param obj 字符串
 * @returns 对象
 */
export const queryStringToObject = (queryString: string) => {
  const obj = {};
  const keyValuePairs = queryString.split("&");
  for (const pair of keyValuePairs) {
    const [key, value] = pair.split("=");
    const decodedKey = decodeURIComponent(key);
    const decodedValue = decodeURIComponent(value);

    obj[decodedKey] = decodedValue;
  }
  return obj;
};

/**
 * @author zzw
 * @date 2023-11-21 18:12:02
 * @desc 加密请求
 * @param {any} params 请求参数
 * @param {string} openId 用户openid
 * @param {string} appSecret 加密秘钥
 */
export function validateRequest(params: any, openId: string, appSecret: string) {
  function stringifyParams(params: any) {
    let unKey = "";

    for (const key in params) {
      if (params[key] === undefined) {
        unKey = key;
      }
      // if (typeof params[key] === "object") {
      //   params[key] = JSON.stringify(params[key]);
      // }
    }
    unKey ? delete params[unKey] : "";

    return params;
  }

  params = stringifyParams(params);
  // 3. 将参数按ASCII编码顺序排序
  const sortedParams = Object.keys(params)
    .sort()
    .map(key => `${key}${params[key]}`)
    .join("");

  // 4. 拼接 appSecret 到参数字符串头尾以及openId
  //signedString='123[zzzappKey1data{"key":"value"}requestId3timestamp1697100220000zzz]123'

  const signedString = `${openId}[${appSecret}${sortedParams}${appSecret}]${openId}`;
  console.log("signedString", signedString);
  // 5. 对整个字符串进行 MD5 哈希并转化为小写16进制
  const sign = MD5(signedString).toString().toLowerCase();
  return sign;
}
//
// /**
//  * @author zzw
//  * @date 2023-12-21 17:01:18
//  * @desc 节流
//  * @param {Function} func 需要节流的函数
//  * @param {number} delay 节流间隔
//  */
// export function throttle<T extends (...args: any[]) => any>(func: T, limit: number): (...args: Parameters<T>) => void {
//   let inThrottle: boolean;
//   let lastFunc: ReturnType<typeof setTimeout>;
//   let lastRan: number;
//
//   return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
//     if (!inThrottle) {
//       func.apply(this, args);
//       lastRan = Date.now();
//       inThrottle = true;
//     } else {
//       clearTimeout(lastFunc);
//       lastFunc = setTimeout(() => {
//         if (Date.now() - lastRan >= limit) {
//           func.apply(this, args);
//           lastRan = Date.now();
//         }
//       }, limit - (Date.now() - lastRan));
//     }
//   };
// }

/**
 * @author zzw
 * @date 2023-12-26 13:51:50
 * @desc 防抖函数
 * @param {Function} func 需要防抖的函数
 * @param {number} delay 防抖间隔
 */
export function debounce<T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => void {
  let timeoutId: ReturnType<typeof setTimeout> | undefined;

  return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

/**判断是否存在最新已发布上线版本，并进行更新 */
export function judgeUpdateManager() {
  const updateManager = Taro.getUpdateManager();
  updateManager.onUpdateReady(() => {
    Taro.showModal({
      title: "更新提示",
      content: "新版本已经准备好，是否重启小程序？",
      success: res => {
        if (res.confirm) {
          // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
          updateManager.applyUpdate();
        }
      },
    });
  });

  updateManager.onUpdateFailed(err => {
    // 新的版本下载失败
    console.log("版本下载失败原因", err);
    Taro.showToast({
      title: "新版本下载失败，请稍后再试",
      icon: "none",
    });
  });
}

/*
    @name: getSystemInfo
    @author: zhangzw
    @date: 2024-01-19 17:19:34
    @LastEditors:zhangzw
    @LastEditTime:2024-01-19 17:19:34
    @params:
    @return:
    @description: 获取设备信息
*/
export function getSystemInfo() {
  return Taro.getSystemInfoSync();
}

/*
    @name: getAppInfo
    @author: zhangzw
    @date: 2024-01-17 09:54:29
    @LastEditors:zhangzw
    @LastEditTime:2024-01-17 09:54:29
    @params:
    @return:
    @description: 获取app长短板以及头部信息
*/
export function getAppInfo() {
  const sysData = Taro.getSystemInfoSync();
  const height = (750 * sysData.screenHeight) / sysData.screenWidth;
  const appInfo = {
    height: height,
    headerHeight: 144,
    platform: sysData.platform,
    type: "",
    appType: "",
  };
  if (height <= 1350) {
    appInfo.type = "minPage";
    appInfo.headerHeight = 116;
    appInfo.appType = "pagemin";
  } else {
    appInfo.type = "maxPage";
    appInfo.headerHeight = 144;
    appInfo.appType = "pagemax";
  }
  appInfo.platform = appInfo.platform.toLowerCase();
  if (appInfo.platform && appInfo.platform.toLowerCase() == "android") {
    appInfo.headerHeight = 150;
  }
  return appInfo;
}

/*
    @name:firstLetter2Upper
    @author: zhangzw
    @date: 2024-01-17 10:09:56
    @LastEditors:zhangzw
    @LastEditTime:2024-01-17 10:09:56
    @params:str
    @return:Str
    @description: 首字母大写
*/
export const firstLetter2Upper = (str: string) => {
  return str.substring(0, 1).toUpperCase() + str.substring(1, str.length);
};

/*
    @name: cryptoData
    @author: zhangzw
    @date: 2024-01-17 10:39:40
    @LastEditors:zhangzw
    @LastEditTime:2024-01-17 10:39:40
    @params:encryptData验签对象
    @return:string 全局签
    @description: 全局验签
*/
export const cryptoData = (encryptData: { [key: string | number]: any }) => {
  // 确定参数加密加密
  const openId = userInfoStore().openId;
  const key = openId.padEnd(32, "0").substring(0, 32);
  const iv = openId.padEnd(16, "0").substring(0, 16);

  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  const appkey = alipayAppInfoStore().activityInfo?.backConfig?.shield?.appkey;
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  const appSecret = alipayAppInfoStore().activityInfo?.backConfig?.shield?.appSecret;

  if (!appkey || !appSecret) {
    console.error("Missing appkey and appSecret. Please contact backend for setup.");
    return false;
  }

  const str = prepareDataString(encryptData, appkey, appSecret);

  return AES.encrypt(str, enc.Utf8.parse(key), {
    iv: enc.Utf8.parse(iv),
    mode: mode.CBC,
    padding: pad.Pkcs7,
  }).ciphertext.toString(enc.Hex);
};

function prepareDataString(info, appkey, appSecret) {
  const sortedKeys = Object.keys(info)
    .filter(key => key !== "allSign" && typeof info[key] !== "object")
    .sort();
  const dataString = sortedKeys.map(key => key + "&" + info[key]).join("");
  return appkey + "[" + appSecret + dataString + appSecret + "]";
}

/*
    @name: scerectSign
    @author: zhangzw
    @date: 2024-01-17 10:39:40
    @LastEditors:zhangzw
    @LastEditTime:2024-01-17 10:39:40
    @params:param验签对象
    @return:string 高风险签
    @description: 高风险验签
*/
export const scerectSign = param => {
  const info = {
    _id: param._id,
    timestamp: param.timestamp,
  };

  const keys = Object.keys(param).sort();
  let str = info._id;
  for (let i = 0; i < keys.length; i++) {
    if (keys[i] == "sign") continue;
    param[keys[i]] = typeof param[keys[i]] == "object" ? JSON.stringify(param[keys[i]]) : param[keys[i]];
    str += keys[i] + "=" + param[keys[i]];
  }
  str += info._id + info.timestamp;
  console.log(str, "===>");

  return MD5(str).toString();
};

/*
    @name: style
    @author: zhangzw
    @date: 2024-01-18 15:16:17
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:16:17
    @params:
    @return:
    @description:样式
*/
export const style = (obj, contain) => {
  let str = "";
  if (obj.zIndex) {
    str += "z-index:" + obj.zIndex + ";";
  }

  if (obj.width) {
    str += "width:" + obj.width + "rpx;";
  }
  if (obj.height) {
    str += "height:" + obj.height + "rpx;";
  }
  if (obj.top) {
    str += "top:" + obj.top + "rpx;";
  }
  if (obj.left) {
    str += "left:" + obj.left + "rpx;";
  }
  if (obj.right) {
    str += "right:" + obj.right + "rpx;";
  }
  if (obj.bottom) {
    str += "bottom:" + obj.bottom + "rpx;";
  }
  if (obj.font) {
    str += "font-size:" + obj.font + "rpx;";
  }
  if (obj.radius) {
    str += "border-radius:" + obj.radius + "rpx;";
  }
  if (obj.color) {
    str += "color:" + obj.color + ";";
  }
  if (obj.lineHeight) {
    str += "line-height:" + obj.lineHeight + "rpx;";
  }
  if (obj.url) {
    str +=
      "background-image:url(" +
      obj.url +
      ");background-repeat:no-repeat;background-size:" +
      (contain || "contain") +
      ";";
  }
  if (obj.bg) {
    str +=
      "background-image:url(" +
      obj.bg +
      ");background-repeat:no-repeat;background-size:" +
      (contain || "contain") +
      ";";
  }
  return str;
};

// export const style = (obj, contain) => {
//   let str = "";
//   if (obj.zIndex) {
//     str += "z-index:" + obj.zIndex + ";";
//   }
//
//   if (obj.width) {
//     str += "width:" + (100 * obj.width) / 750 + "vw;";
//   }
//   if (obj.height) {
//     str += "height:" + (100 * obj.height) / 750 + "vw;";
//   }
//   if (obj.top) {
//     str += "top:" + (100 * obj.top) / 750 + "vw;";
//   }
//   if (obj.left) {
//     str += "left:" + (100 * obj.left) / 750 + "vw;";
//   }
//   if (obj.right) {
//     str += "right:" + (100 * obj.right) / 750 + "vw;";
//   }
//   if (obj.bottom) {
//     str += "bottom:" + (100 * obj.bottom) / 750 + "vw;";
//   }
//   if (obj.font) {
//     str += "font-size:" + (100 * obj.font) / 750 + "vw;";
//   }
//   if (obj.radius) {
//     str += "border-radius:" + (100 * obj.radius) / 750 + "vw;";
//   }
//   if (obj.color) {
//     str += "color:" + obj.color + ";";
//   }
//   if (obj.lineHeight) {
//     str += "line-height:" + (100 * obj.lineHeight) / 750 + "vw;";
//   }
//   if (obj.url) {
//     str +=
//       "background-image:url(" +
//       obj.url +
//       ");background-repeat:no-repeat;background-size:" +
//       (contain || "contain") +
//       ";";
//   }
//   if (obj.bg) {
//     str +=
//       "background-image:url(" +
//       obj.bg +
//       ");background-repeat:no-repeat;background-size:" +
//       (contain || "contain") +
//       ";";
//   }
//   return str;
// };

export const width = width => {
  return `width:${(100 * width) / 750}vw;`;
};

export const height = height => {
  return `height:${(100 * height) / 750}vw;`;
};

export const top = top => {
  return `top:${(100 * top) / 750}vw;`;
};

export const left = left => {
  return `left:${(100 * left) / 750}vw;`;
};

export const bottom = bottom => {
  return `bottom:${(100 * bottom) / 750}vw;`;
};
export const right = right => {
  return `right:${(100 * right) / 750}vw;`;
};

export const font = font => {
  return `font-size:${(100 * font) / 750}vw;`;
};

export const margin = (px, pos) => {
  if (pos) {
    return `margin-${pos}:${(100 * px) / 750}vw;`;
  } else {
    return `margin:${(100 * px) / 750}vw;`;
  }
};

export const lineHeight = px => {
  return `line-height:${(100 * px) / 750}vw;`;
};

export const padding = (px, pos) => {
  if (pos) {
    return `padding-${pos}:${(100 * px) / 750}vw;`;
  } else {
    return `padding:${(100 * px) / 750}vw;`;
  }
};

/*
    @name: isEmpty
    @author: zhangzw
    @date: 2024-01-18 15:18:28
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:18:28
    @params:
    @return:
    @description: 判断对象是否为空
*/
export const isEmpty = (obj?: Record<string, any>) => {
  return obj && JSON.stringify(obj) != "{}" ? false : true;
};

/*
    @name: timestamp2str
    @author: zhangzw
    @date: 2024-01-18 15:19:34
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:19:34
    @params:
    @return:
    @description: 时间戳转化为年月日
*/
export const timestamp2str = (time, type, isHour) => {
  const date = time ? new Date(time) : new Date();
  let str =
    date.getFullYear() +
    (type ? type : "年") +
    getTwoNum(date.getMonth() + 1) +
    (type ? type : "月") +
    getTwoNum(date.getDate()) +
    (type ? "" : "日");
  if (isHour) {
    str += " " + getTwoNum(date.getHours()) + ":" + getTwoNum(date.getMinutes()) + ":" + getTwoNum(date.getSeconds());
  }
  return str;
};

/*
    @name:getTimeLong
    @author: zhangzw
    @date: 2024-01-18 15:21:35
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:21:35
    @params:
    @return:
    @description:时间转化为时间戳
*/
export const getTimeLong = str => {
  if (!str) {
    return new Date().getTime();
  }
  let date = new Date(str).getTime();
  if (isNaN(date)) {
    str = str.replace(/-/gi, "/");
    date = new Date(str).getTime();
  }
  return date;
};

/*
    @name: getTwoNum
    @author: zhangzw
    @date: 2024-01-18 15:19:57
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:19:57
    @params:
    @return:
    @description: 0-9转化为00 01 02 03 04 05 06 07 08 09
*/
export const getTwoNum = (num: number) => {
  return num < 10 && num >= 0 ? "0" + num : num + "";
};

/*
    @name: getMonthDate
    @author: zhangzw
    @date: 2024-01-18 15:20:46
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:20:46
    @params:
    @return:
    @description: 获取指定月份有多少天
*/
export const getMonthDate = (year, month) => {
  return new Date(year, month, 0).getDate();
};

/*
    @name: toast
    @author: zhangzw
    @date: 2024-01-18 15:21:09
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:21:09
    @params:
    @return:
    @description: 弱提示
*/
export const toast = (txt: string, duration = 1500) => {
  Taro.showToast({
    title: txt,
    icon: "none",
    duration: duration,
  });
};

/*
    @name: timerCounter
    @author: zhangzw
    @date: 2024-01-18 15:22:08
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:22:08
    @params:
    @return:
    @description: 倒计时
*/
export const timerCounter = (endTime: string) => {
  const ld = getTimeLong(endTime);
  const now = new Date().getTime();
  let config: string[] = ["00", "00", "00", "00"];
  if (ld <= now) {
    config = ["00", "00", "00", "00"];
  } else {
    const substract = Math.floor((ld - now) / 1000);
    const second = getTwoNum(substract % 60);
    const minute = getTwoNum(Math.floor(substract / 60) % 60);
    const hour = getTwoNum(Math.floor(substract / (60 * 60)) % 24);
    const day = getTwoNum(Math.floor(substract / (60 * 24 * 60)));
    config = [day, hour, minute, second];
  }
  return config;
};

/*
    @name: getShareUrl
    @author: zhangzw
    @date: 2024-01-18 15:22:44
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:22:44
    @params:
    @return:
    @description: 获取分享链接
*/
export const getShareUrl = (page, shareQuery = {}, isPath) => {
  return getAppUrl(page, shareQuery, true, isPath);
};

export const getAppUrl = (page, params = {}, isShare, isPath) => {
  page = page ? page : "pages/index/index";
  const base =
    alipayAppInfoStore().env == "test"
      ? alipayAppInfoStore().appConfig.C.appDebugUrl
      : alipayAppInfoStore().appConfig.C.appUrl;
  const query = queryFn(params || {});

  return isPath
    ? !isShare
      ? `${base}&page=${page}?` + encodeURIComponent(`${query}`)
      : `${page}?` + `${query}`
    : `${base}&page=${page}?` + encodeURIComponent(`${query}`);
};

export const queryFn = params => {
  params = params || {};
  return Object.keys(params)
    .map(k => `${k}=${params[k]}`)
    .join("&");
};

/*
    @name: sortArr
    @author: zhangzw
    @date: 2024-01-18 15:26:07
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:26:07
    @params:
    @return:
    @description: 数组排序
*/
export const sortArr = (arr, attr = "key", flag = true) => {
  for (let i = 0; i < arr.length - 1; i++) {
    //比较arr.length-1轮
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i][attr] > arr[j][attr] && flag == true) {
        //交换
        const temp = arr[i]; //临时变量
        arr[i] = arr[j];
        arr[j] = temp;
      } else if (arr[i][attr] < arr[j][attr] && flag == false) {
        const temp = arr[i]; //临时变量
        arr[i] = arr[j];
        arr[j] = temp;
      }
    }
  }
  return arr;
};

/*
    @name: sortRandom
    @author: zhangzw
    @date: 2024-01-18 15:26:23
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:26:23
    @params:
    @return:
    @description: 随机排序
*/
export const sortRandom = (list: any[]) => {
  return list.sort(function () {
    return Math.random() > 0.5 ? -1 : 1;
  });
};

/*
    @name: isEnd
    @author: zhangzw
    @date: 2024-01-18 15:43:19
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:43:19
    @params:
    @return:
    @description: 活动是否结束  true已结束 false未结束
*/
export const isEnd = endTimeStr => {
  const endTimeLong = getTimeLong(endTimeStr);
  const now = new Date().getTime();
  return now > endTimeLong;
};

/*
    @name: isStart
    @author: zhangzw
    @date: 2024-01-18 15:43:42
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:43:42
    @params:
    @return:
    @description: 活动是否结开始  true已开始 false未开始
*/
export const isStart = startTimeStr => {
  const startTimeLong = getTimeLong(startTimeStr);
  const now = new Date().getTime();
  return now > startTimeLong;
};

/*
    @name:trim
    @author: zhangzw
    @date: 2024-01-18 15:50:54
    @LastEditors:zhangzw
    @LastEditTime:2024-01-18 15:50:54
    @params:
    @return:
    @description:去除左右空格
*/
export const trim = s => s.replace(/(^\s*)|(\s*$)/g, "");

/**
 * @author zzw
 * @date 2023-12-21 17:01:18
 * @desc 节流
 * @param {Function} func 需要节流的函数
 * @param {number} delay 节流间隔
 */
export function throttle<T extends (...args: any[]) => any>(func: T, limit: number): (...args: Parameters<T>) => void {
  let inThrottle: boolean;
  let lastFunc: ReturnType<typeof setTimeout>;
  let lastRan: number;

  return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
    if (!inThrottle) {
      func.apply(this, args);
      lastRan = Date.now();
      inThrottle = true;
    } else {
      clearTimeout(lastFunc);
      lastFunc = setTimeout(() => {
        if (Date.now() - lastRan >= limit) {
          func.apply(this, args);
          lastRan = Date.now();
        }
      }, limit - (Date.now() - lastRan));
    }
  };
}

export const getImageInfo = url => {
  console.log(url);
  return new Promise((resolve, reject) => {
    Taro.getImageInfo({
      src: url,
      success(res) {
        resolve(res);
      },
      fail(err) {
        reject(err);
      },
    });
  });
};

export const getParams = paramsName => {
  const url = window.location.href;
  const urlParts = url.split("?");
  const paramsString = urlParts[1];
  const paramsArr = paramsString.split("&");
  const params = {};
  paramsArr.forEach(item => {
    const objArr = item.split("=");
    params[objArr[0]] = objArr[1].replace("#/pages/index/index", "");
  });
  return params[paramsName];
};

/**
 * 获取当前周的起止日期（周一至周日）
 * @returns {Object} { startDate: Date, endDate: Date }
 */
export const getCurrentWeekRange = () => {
  const now = new Date();
  const day = now.getDay(); // 0是周日，1是周一，...，6是周六
  const diffToMonday = day === 0 ? -6 : 1 - day; // 如果是周日，需要减去6天

  // 计算周一日期
  const startDate = new Date(now);
  startDate.setDate(now.getDate() + diffToMonday);
  startDate.setHours(0, 0, 0, 0);

  // 计算周日日期
  const endDate = new Date(startDate);
  endDate.setDate(startDate.getDate() + 6);
  endDate.setHours(23, 59, 59, 999);

  // 格式化日期为YYYY-MM-DD（自动补零）
  const formatDate = date => {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份补零
    const day = String(date.getDate()).padStart(2, "0"); // 日期补零
    return `${year}-${month}-${day}`;
  };

  return {
    startDate: formatDate(startDate),
    endDate: formatDate(endDate),
  };
};

// 获取字典
export const getDicts = async (dictType: any) => {
  return new Promise((resolve, reject) => {
    getDictDataTypeList(dictType)
      .then(res => {
        if (res.code === 200) {
          resolve(res.data);
        } else {
          reject(new Error(res.message || "获取字典失败"));
        }
      })
      .catch(error => {
        reject(error);
      });
  });
};

// 转换时间格式 yyyy-MM-dd
export const formatDates = time => {
  const date = new Date(time);
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  return `${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}`;
};
// 转换时间格式 yyyy-MM-dd HH:mm:ss
export const formaTime = time => {
  const date = new Date(time);
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  const hour = date.getHours();
  const minute = date.getMinutes();
  const second = date.getSeconds();

  return `${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")} ${hour
    .toString()
    .padStart(2, "0")}:${minute.toString().padStart(2, "0")}:${second.toString().padStart(2, "0")}`;
};
// 转换时间格式 HH:mm:ss
export const times = time => {
  const date = new Date(time);
  // const year = date.getFullYear();
  // const month = date.getMonth() + 1;
  // const day = date.getDate();
  const hour = date.getHours();
  const minute = date.getMinutes();
  const second = date.getSeconds();

  return `${hour.toString().padStart(2, "0")}:${minute.toString().padStart(2, "0")}:${second
    .toString()
    .padStart(2, "0")}`;
};
// 月
export const formatDateMonths = (dateTime) => {
  const date = new Date(dateTime);
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  return `${year}年${month}月`;
};
// 日
export const formatDateChinese = (dateTime: string) => {
  const date = new Date(dateTime);
  const weekdays = ["日", "一", "二", "三", "四", "五", "六"];

  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  const weekday = weekdays[date.getDay()];
  return `${year}年${month}月${day}日（周${weekday}）`;
};
